
#include <asm-generic/errno-base.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>

union semun {
               int              val;    /* Value for SETVAL */
               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
               unsigned short  *array;  /* Array for GETALL, SETALL */
               struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                           (Linux-specific) */
           };
void sem_p(int,int);
void sem_v(int,int);

int main(int argc,char* argv[]){
  key_t key = ftok(".",1);
  if(key < 0){
    perror("ftok fail");
    exit(-1);
  }
  
  int sem_id = semget(key,3,IPC_CREAT | IPC_EXCL | 0666);
  if(sem_id < 0){
    if(errno == EEXIST){
      sem_id = semget(key,3,   0666);
    }
  }else if(sem_id > 0){
    union semun a;
    a.val = 1;
    semctl(sem_id,0,SETVAL,a);
    a.val = 0;
    semctl(sem_id,1,SETVAL,a);
    a.val = 0;
    semctl(sem_id,2,SETVAL,a);
  }

  while(1){
    sem_p(sem_id,1);
    printf("wolrd\n");
    sem_v(sem_id,2);
    sleep(1);
  }

  semctl(sem_id,0,IPC_RMID,NULL);

  return 0;
}
void sem_p(int sem_id, int num) {
  struct sembuf a;
  a.sem_num = num;
  a.sem_flg = 0;
  a.sem_op = -1;
  semop(sem_id, &a, 1);
}
void sem_v(int sem_id, int num) {
  struct sembuf a;
  a.sem_num = num;
  a.sem_flg = 0;
  a.sem_op = 1;
  semop(sem_id, &a, 1);
}
